package com.jysz.certificate.web.action.cs;

import java.io.File;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.jysz.certificate.action.AbstractBaseAction;
import com.jysz.certificate.persistence.enums.AttachmentType;
import com.jysz.certificate.persistence.enums.CertificationType;
import com.jysz.certificate.persistence.enums.cs.CheckStockStatus;
import com.jysz.certificate.persistence.enums.cs.OptionStatus;
import com.jysz.certificate.persistence.model.cm.Certification;
import com.jysz.certificate.persistence.model.core.Attachment;
import com.jysz.certificate.persistence.model.cs.CheckObject;
import com.jysz.certificate.persistence.model.cs.CheckStock;
import com.jysz.certificate.persistence.model.cs.CheckStockOption;
import com.jysz.certificate.persistence.model.system.Brand;
import com.jysz.certificate.persistence.model.system.Financial;
import com.jysz.certificate.persistence.model.system.Organization;
import com.jysz.certificate.persistence.model.system.Shop;
import com.jysz.certificate.service.cm.CertificationService;
import com.jysz.certificate.service.core.AttachmentService;
import com.jysz.certificate.service.cs.CheckStockOptionService;
import com.jysz.certificate.service.cs.CheckStockService;
import com.jysz.certificate.service.system.BrandService;
import com.jysz.certificate.service.system.FinancialService;
import com.jysz.certificate.service.system.OrganizationService;
import com.jysz.certificate.service.system.ShopService;
import com.jysz.certificate.service.system.UserService;
import com.jysz.certificate.utils.CommonUtil;
import com.jysz.certificate.utils.PoiUtils;
import com.jysz.webcore.ssh.orm.hibernate.support.Page;

/**
 * 盘库
 * @author xuxiaolong
 */
@Controller
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Namespace("/cs")
public class CheckStockAction extends AbstractBaseAction {

	private static final long serialVersionUID = -3690085377133333730L;
	
	@Resource
	private CheckStockService csService;
	@Resource
	private CheckStockOptionService optionService;
	@Resource
	private UserService userService;
	@Resource
	private CertificationService cfService;
	@Resource
	private AttachmentService attService;
	@Resource
	private ShopService shopService;
	@Resource
	private OrganizationService organService;
	@Resource
	private BrandService brandService;// 主机厂service
	@Resource
	private FinancialService financialService;// 金融机构service
	private CheckStock search;
	private CheckStock entity;
	private CheckStockOption option;
	private Integer status;
	private String operate;
	private File file;
	private String fileFileName;//文件名称 
	private String fileContentType;	//文件类型  
	private List<Attachment> attachs;//附件
	private List<Organization> orgList;//组织架构 驻店员
	
	private String pageData;//当前页数据
	private String allData;//全局数据
	private List<Financial> fiList;
	private List<Brand> brandList;
	private Integer success;
	
	
	@Action(INDEX)
	public String index(){
		if(search==null)
			search=new CheckStock();
		if(status!=null&&status>=0){
			search.setStatus(CheckStockStatus.index(status)) ;
		}
		if(success!=null&&success!=0){
			if(success==1)
				search.setSuccess(true);
			else
				search.setSuccess(false);
		}else
			search.setSuccess(null);
		setPage(csService.findPage(search,getCurrentPage(), getPageSize()));
		return INDEX;
	}
	
	@Action("exportStore")
	public String exportStore(){
		entity=csService.find(entity.getId());
		List<Certification> cfs = cfService.findCfByShopId(entity.getShop().getId());
		
		HashSet<Integer> lines = new HashSet<Integer>();
		
		if(cfs != null && cfs.size() > 0){
			for (int i = 0; i < cfs.size(); i++) {
				
				if(cfs.get(i).getChange()){
					lines.add(i);
				}else{
					//查询排序已经将二网的库存排在前面，遇到没有二网的可以直接跳出循环。
					break;
				}
			}
		}
		
		
		String[] headers = {"主机厂", "金融机构", "合格证号", "车架号", "发动机号", "车型", "单价", "入库时间"};
		String[] columns = {"brand.name", "financial.name", "certificationNum", "chassis", "engine", "motorcycleType", "supplyPrice", "warehouseDate" };
		HttpServletResponse response = this.getResponse();
	    response.setContentType("octets/stream");
	    response.addHeader("Content-Disposition",
	                "attachment;filename=" + toUtf8Encode(entity.getShop().getShopName()+"_库存清单") + ".xls");
		OutputStream out = null;
		try {
			out = this.getResponse().getOutputStream();
			Map<String, Object> context = new HashMap<String, Object>();

			PoiUtils.exportExcel(entity.getShop().getShopName()+"_库存清单", headers, columns, cfs, out, null, context, lines);
		} catch (Exception e) {
			LOG.error("导出库存清单出错。。。", e);
		}
		
		return null;
	}
	
	@Action(ADD)
	public String add(){
		if(entity == null)
			entity = new CheckStock();
		if(entity.getShop() != null && entity.getShop().getId()!=null){
			Shop shop=shopService.find(entity.getShop().getId());
			if(shop!=null){
				orgList=organService.findUserShopByShopId(entity.getShop().getId());
				//根据驻店员设置店铺
				entity.setShop(shop);
				List<Organization> areaList=organService.findUserDomainByShopId(entity.getShop().getId());
				if(areaList!=null&&areaList.size()>0){
					entity.setAreaManager(userService.find(areaList.get(0).getObjectId())); 
				}
				//设置该店铺下所有在库的合格证 
				setPage(cfService.findPage(shop.getId(), getCurrentPage(), getPageSize()));
			}
			
		}
		
		//set 发起人
		entity.setSponsor(getUser());
		//设置发起人是 总部、还是监管科、还是区域经理 
		entity.setSource(getUser().getPost());
		return ADD;
	}
	
	@Action(CREATE)
	public String create(){
		entity.setSource(getUser().getPost());
		if("save".equals(operate)){
			entity.setSponsor(getUser());
			entity.setStatus(CheckStockStatus.UNSTART);
		}
		/*else{
			entity.setStatus(CheckStockStatus.SUBMITED);
			entity.setSubmitDate(new Date());
		}*/
		csService.create(entity);
		setSuccessPopMessage("操作成功");
		setRedirectUrl("preConfirm.do?entity.id="+entity.getId());
		return SHOW_MSG_PAGE;
	}
	
	@Action(EDIT)
	public String edit(){
		
		entity=csService.find(entity.getId());
		orgList=organService.findUserShopByShopId(entity.getShop().getId());
		setPage(cfService.findPage(entity.getShop().getId(), getCurrentPage(), getPageSize()));
		return ADD;
	}
	
	/**
	 * 准备确认
	 */
	@Action("preConfirm")
	public String preConfirm(){
		entity=csService.find(entity.getId());
		setPage(optionService.findPage(entity.getId(),option, getCurrentPage(), 30));
		buildData(entity,entity.getStatus());
		attachs=attService.findAll(null, entity.getId(), AttachmentType.CHECKSTOCK);
		
		fiList = financialService.finList();
		brandList = brandService.findAll();
		
		return "confirm";
	}
	
	/**
	 * 分页
	 */
	@Action("jumpPage")
	public String jumpPage(){
		String remark=entity.getRemark();
		entity=csService.find(entity.getId());
		entity.setRemark(remark);
		setPage(optionService.findPage(entity.getId(),option, getCurrentPage(),30));
		buildData(entity.getStatus());
		attachs=attService.findAll(getUser(), entity.getId(), AttachmentType.CHECKSTOCK);
		
		fiList = financialService.finList();
		brandList = brandService.findAll();
		
		return "confirm";
	}
	
	@Action("confirm")
	public String confirm(){
		CheckStock cs=buildSaveData();
		/*if(cs.getStatus().compareTo(CheckStockStatus.SUBMITED)==0){
			cs.setStatus(CheckStockStatus.CONFIRM_SHOP);
			csService.save(cs,file,fileFileName,getUser());
			setSuccessPopMessage("盘库确认成功");
		}else if(cs.getStatus().compareTo(CheckStockStatus.CONFIRM_SHOP)==0){*/
		//检查盘库是成功或失败,状态改为已完成
		String rus=check(cs);
		cs.setFinishDate(new Date());
		if(CommonUtil.isEmpty(rus)){
			cs.setStatus(CheckStockStatus.FINISHED);
			cs.setSuccess(true);//成功
			cs.setResultRemark(null);
			csService.save(cs,file,fileFileName,getUser());
			setSuccessPopMessage("盘库确认成功");
			setRedirectUrl("index.do");
		}
		//比对结果不一致,转到中间页面,生成备注
		else{
//			cs.setStatus(CheckStockStatus.FINISHED);
//			cs.setSuccess(false);//失败
			cs.setResultRemark("车架号 "+rus+" 状态不对");
			csService.save(cs,file,fileFileName,getUser());
			setSuccessPopMessage("盘库确认失败");
			setRedirectUrl("fail.do?entity.id="+cs.getId());
//			csService.reset(entity.getId());
//			setSuccessPopMessage("与驻店员确认结果不一致,系统已重新发起盘库！");
		}
		
//		}
		return SHOW_MSG_PAGE;
	}
	
	@Action("save")
	public String save(){
		
		csService.save(buildSaveData(),file,fileFileName,getUser()) ;
		return jumpPage();
		/*setRedirectUrl("index.do");
		setSuccessPopMessage("操作成功");
		return SHOW_MSG_PAGE;*/
	}
	
	@Action("fail")
	public String fail(){

		entity = csService.find(entity.getId());
		setPage(optionService.findPage(entity.getId(),option, getCurrentPage(),getPageSize()));
		attachs=attService.findAll(null, entity.getId(), AttachmentType.CHECKSTOCK);
		
		fiList = financialService.finList();
		brandList = brandService.findAll();
		
		setRedirectUrl("index.do?currentPage="+getCurrentPage(),"search",search);
		return "fail";
	}
	
	@Action("saveFail")
	public String saveFail(){
		CheckStock cs= csService.find(entity.getId());
		cs.setRemark(entity.getRemark());
		if("checkin".equals(operate)){
			cs.setStatus(CheckStockStatus.FINISHED);
			cs.setSuccess(false);//失败
		}else{
		}
		
		csService.save(cs);
		setSuccessPopMessage("操作成功");
		return SHOW_MSG_PAGE;
	}
	
	@Action("reset")
	public String reset(){
		csService.reset(entity.getId());
		setRedirectUrl("index.do");
		setSuccessPopMessage("操作成功");
		return SHOW_MSG_PAGE;
	}
	
	
	@Action(DESTORY)
	public String destory(){
		if(entity!=null&&entity.getId()!=null)
			csService.destory(entity.getId());
		setRedirectUrl("index.do?currentPage="+getCurrentPage(),"search",search);
		setSuccessPopMessage("删除成功");
		return SHOW_MSG_PAGE;
	}
	
	@Action("view")
	public String view(){
		
		entity = csService.find(entity.getId());
		setPage(optionService.findPage(entity.getId(),option, getCurrentPage(),getPageSize()));
		attachs=attService.findAll(null, entity.getId(), AttachmentType.CHECKSTOCK);
		
		fiList = financialService.finList();
		brandList = brandService.findAll();
		
		setRedirectUrl("index.do?currentPage="+getCurrentPage(),"search",search);
		return "view";
	}

	@Action("exportView")
	public String exportView() {
		entity = csService.find(entity.getId());
		HttpServletResponse response = this.getResponse();
	    response.setContentType("octets/stream");
	    response.addHeader("Content-Disposition",
	                "attachment;filename=" + toUtf8Encode("盘库详情表") + ".xls");
		OutputStream out = null;
		try {
			String[] headers = {"序号", "渠道","金融机构","合格证号", "车架号","发动机号","车型","单价","入库日期", "合格证状态",
					"车辆状态", "二库地址", "备注" };
			String[] columns = {"#index","certification.brand.name", "certification.financial.name","certification.certificationNum","certification.chassis", "certification.engine","certification.motorcycleType","certification.supplyPrice", "certification.warehouseDate", "cfStatusArea!=null?cfStatusArea.name:''","carStatusArea!=null?carStatusArea.name:''","certification.theAddress","remark"};
			List<CheckStockOption> list=optionService.findList(entity.getId(),option);
			out = this.getResponse().getOutputStream();
			Map<String, Object> context = new HashMap<String, Object>();
			context.put("cfa", this);
			PoiUtils.exportExcelCheckStockView(entity,"盘库详情表", out,columns,headers,list, null, context, null);
		} catch (Exception e) {
			e.printStackTrace();
			LOG.error("导出盘库详情表出错。。。", e);
		}
		
		return null;
	}
	
	/** 第一次进入确认页面 封装数据*/
	@SuppressWarnings("unchecked")
	public void buildData(CheckStock cs,CheckStockStatus status){
		Page<CheckStockOption> page=(Page<CheckStockOption>) getPage();
		//当前页的数据
		List<CheckStockOption> pageList=page.getResult();
		List<CheckStockOption> rus=new ArrayList<CheckStockOption>();
		//当前页数据
		setPageData(getJsonStr(pageList,status));
		for(CheckStockOption tmp:cs.getOptions()){
			if(!pageList.contains(tmp)){
				rus.add(tmp);
			}
		}
		setAllData(getJsonStr(rus,cs.getStatus())) ;
		
	}
	
	/** 第N次进入*/
	@SuppressWarnings("unchecked")
	public void buildData(CheckStockStatus status){
		Gson gson = new Gson();
		Page<CheckStockOption> page=(Page<CheckStockOption>) getPage();
		//当前页的数据
		List<CheckStockOption> pageList=page.getResult();
		
		List<CheckObject> pageObjectList=getObjectList(pageList,status);
		
	    JsonParser parser = new JsonParser(); 
	    JsonArray Jarray = parser.parse(getAllData()).getAsJsonArray(); 
	    ArrayList<CheckObject> rusAll = new ArrayList<CheckObject>(); 
	    ArrayList<CheckObject> rusPage= new ArrayList<CheckObject>(); 
	    for(JsonElement obj : Jarray ){ 
	    	CheckObject to = gson.fromJson( obj , CheckObject.class);
	    	//不在当前页才存放到全局
	    	if(pageObjectList.contains(to))
	    		rusPage.add(to); 
	    	else
	    		rusAll.add(to);
	    } 
	    
	    //当前页数据
		setPageData(gson.toJson(rusPage));
	    
	    //全局数据
	     setAllData(gson.toJson(rusAll));
	     
	}
	
	/** 构建保存到数据库的数据*/
	public CheckStock buildSaveData(){
		CheckStock cs= csService.find(entity.getId());
		cs.setRemark(entity.getRemark());
		cs.setLive(entity.getLive());
		Gson gson=new Gson();
		JsonParser parser = new JsonParser(); 
	    JsonArray Jarray = parser.parse(getAllData()).getAsJsonArray(); 
	    List<CheckStockOption> options = new ArrayList<CheckStockOption>();
	    CheckStockOption tmp=null;
	    //区域经理
//	    if(cs.getStatus().compareTo(CheckStockStatus.CONFIRM_SHOP)==0){
	    	for(JsonElement obj : Jarray ){
		    	CheckObject to = gson.fromJson( obj , CheckObject.class);
		    	tmp=optionService.find(to.getId());
		    	if(to.getCk00()==1)
		    		tmp.setCfStatusArea(OptionStatus.INSTOCK);
		    	else if(to.getCk00()==0)
		    		tmp.setCfStatusArea(OptionStatus.OUTSTOCK);
		    	if(to.getCk10()==1)
		    		tmp.setCarStatusArea(OptionStatus.INSTOCK);
		    	else if(to.getCk10()==0)
		    		tmp.setCarStatusArea(OptionStatus.OUTSTOCK);
		    	else if(to.getCk10()==2)
		    		tmp.setCarStatusArea(OptionStatus.NOMATTER);
		    	tmp.setRemark(to.getMsg());
		    	options.add(tmp);
		    } 
//	    }
	    //驻店员
	   /* else if(cs.getStatus().compareTo(CheckStockStatus.SUBMITED)==0){
	    	for(JsonElement obj : Jarray ){
		    	CheckObject to = gson.fromJson( obj , CheckObject.class);
		    	tmp=optionService.find(to.getId());
		    	if(to.getCk00()==1)
		    		tmp.setCfStatus(OptionStatus.INSTOCK);
		    	else if(to.getCk00()==0)
		    		tmp.setCfStatus(OptionStatus.OUTSTOCK);
		    	if(to.getCk10()==1)
		    		tmp.setCarStatus(OptionStatus.INSTOCK);
		    	else if(to.getCk10()==0)
		    		tmp.setCarStatus(OptionStatus.OUTSTOCK);
		    	tmp.setRemark(to.getMsg());
		    	options.add(tmp);
		    } 
	    }
	    */
	    cs.setOptions(options);
		return cs;
	}
	
	public List<CheckObject> getObjectList(List<CheckStockOption> list,CheckStockStatus status){
		
		List<CheckObject> rus=new ArrayList<CheckObject>();
		CheckObject co=null;
		//区域经理确认
//	    if(status.compareTo(CheckStockStatus.CONFIRM_SHOP)==0){
	    	for(CheckStockOption tmp:list){
				co=new CheckObject();
				co.setId(tmp.getId());
				if(tmp.getCfStatusArea()==null){
					co.setCk00(-1);
				}else if(tmp.getCfStatusArea().compareTo(OptionStatus.INSTOCK)==0){
					co.setCk00(1);
				}else{
					co.setCk00(0);
				}
				
				if(tmp.getCarStatusArea()==null){
					co.setCk10(-1);
				}else if(tmp.getCarStatusArea().compareTo(OptionStatus.INSTOCK)==0){
					co.setCk10(1);
				}else if(tmp.getCarStatusArea().compareTo(OptionStatus.OUTSTOCK)==0){
					co.setCk10(0);
				}else if(tmp.getCarStatusArea().compareTo(OptionStatus.NOMATTER)==0){
					co.setCk10(2);
				}
				co.setMsg(tmp.getRemark());
				rus.add(co);
			}
//	    }
	    //驻店员确认
	   /* else if(status.compareTo(CheckStockStatus.SUBMITED)==0){
	    	for(CheckStockOption tmp:list){
				co=new CheckObject();
				co.setId(tmp.getId());
				if(tmp.getCfStatus()==null){
					co.setCk00(-1);
				}else if(tmp.getCfStatus().compareTo(OptionStatus.INSTOCK)==0){
					co.setCk00(1);
				}else{
					co.setCk00(0);
				}
				
				if(tmp.getCarStatus()==null){
					co.setCk10(-1);
				}else if(tmp.getCarStatus().compareTo(OptionStatus.INSTOCK)==0){
					co.setCk10(1);
				}else{
					co.setCk10(0);
				}
				co.setMsg(tmp.getRemark());
				rus.add(co);
			}
	    }*/
		return rus;
	}
	
	public String getJsonStr(List<CheckStockOption> list,CheckStockStatus status){
		Gson gson=new Gson();
		return gson.toJson(getObjectList(list,status));
	}
	
	/** 按照盘库成功规则,逐条确认*/
	private String check(CheckStock cs){
		StringBuilder sb=new StringBuilder();
		for(CheckStockOption option:cs.getOptions()){
			/**
			 * 成功规则
			 * 状态		合格证状态		车辆状态
			 * 在库			在库			在库或不管车
			 * 在库二网		在库			不在库或不管车
			 * 已释放		不在库		不在库或不管车
			 */
			//在库
			if(option.getCertification().getState().compareTo(CertificationType.INSTOCK)==0&&CommonUtil.isEmpty(option.getCertification().getTheAddress())){
				if(option.getCfStatusArea().compareTo(OptionStatus.INSTOCK)!=0||option.getCarStatusArea().compareTo(OptionStatus.OUTSTOCK)==0){
					sb.append(option.getCertification().getChassis()).append(",");
				}
			}
			//在库二网
			else if(option.getCertification().getState().compareTo(CertificationType.INSTOCK)==0&&CommonUtil.isNotEmpty(option.getCertification().getTheAddress())){
				if(option.getCfStatusArea().compareTo(OptionStatus.INSTOCK)!=0||option.getCarStatusArea().compareTo(OptionStatus.INSTOCK)==0){
					sb.append(option.getCertification().getChassis()).append(",");
				}
			}
			//已释放
			else if(option.getCertification().getState().compareTo(CertificationType.RELEASEED)==0){
				if(option.getCfStatusArea().compareTo(OptionStatus.INSTOCK)==0||option.getCarStatusArea().compareTo(OptionStatus.INSTOCK)==0){
					sb.append(option.getCertification().getChassis()).append(",");
				}
			}
		}
		String rus=sb.toString();
		if(rus!=null&&rus.length()>0)
			rus=rus.substring(0, rus.length()-1);
		return rus;
	}
	
	public CheckStock getSearch() {
		return search;
	}

	public void setSearch(CheckStock search) {
		this.search = search;
	}

	public CheckStock getEntity() {
		return entity;
	}

	public void setEntity(CheckStock entity) {
		this.entity = entity;
	}

	public String getOperate() {
		return operate;
	}

	public void setOperate(String operate) {
		this.operate = operate;
	}

	public String getPageData() {
		return pageData;
	}

	public void setPageData(String pageData) {
		this.pageData = pageData;
	}

	public String getAllData() {
		return allData;
	}

	public void setAllData(String allData) {
		this.allData = allData;
	}

	public File getFile() {
		return file;
	}

	public void setFile(File file) {
		this.file = file;
	}

	public String getFileFileName() {
		return fileFileName;
	}

	public void setFileFileName(String fileFileName) {
		this.fileFileName = fileFileName;
	}

	public String getFileContentType() {
		return fileContentType;
	}

	public void setFileContentType(String fileContentType) {
		this.fileContentType = fileContentType;
	}

	public List<Attachment> getAttachs() {
		return attachs;
	}

	public void setAttachs(List<Attachment> attachs) {
		this.attachs = attachs;
	}

	public Integer getStatus() {
		return status;
	}

	public void setStatus(Integer status) {
		this.status = status;
	}

	public CheckStockOption getOption() {
		return option;
	}

	public void setOption(CheckStockOption option) {
		this.option = option;
	}

	public List<Organization> getOrgList() {
		return orgList;
	}

	public void setOrgList(List<Organization> orgList) {
		this.orgList = orgList;
	}

	public List<Financial> getFiList() {
		return fiList;
	}

	public void setFiList(List<Financial> fiList) {
		this.fiList = fiList;
	}

	public List<Brand> getBrandList() {
		return brandList;
	}

	public void setBrandList(List<Brand> brandList) {
		this.brandList = brandList;
	}

	public Integer getSuccess() {
		return success;
	}

	public void setSuccess(Integer success) {
		this.success = success;
	}

}
